package com.dq.rbac.commons.security;

import com.dq.rbac.entity.SysUser;
import com.dq.rbac.service.SysUserService;
import com.dq.rbac.utils.JWTUtils;
import com.dq.rbac.utils.JwtUtil;
import io.jsonwebtoken.JwtException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

/**
 * @project: rbac
 * @ClassName: 自定义Jwt身份验证筛选器
 * @author: dq33
 * @creat: 2022/12/26 16:09
 */
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    @Resource
    private SysUserService userService;
    @Resource
    private MyUserDetailServiceImpl userDetailService;

    private static final String URL_WHITELIST[] = {
            "/login",
            "/logout",
            "/captcha",
            "/password",
            "/image/**",
    };

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        //1. 获取请求头中的token
        String token = request.getHeader("token");
        //2. 获取请求URL 匹配白名单放行
        System.out.println("请求URL = " + request.getRequestURI());
        if (token == null || token.isEmpty() || Arrays.asList(URL_WHITELIST).contains(request.getRequestURI())) { //如果token为NULL 或者 URL在白名单我们就放心 利用后面的Filter判断
            chain.doFilter(request, response);
            return;
        }

        if (!JwtUtil.isSigned(token)) {
            throw new JwtException("token不存在");
        }
        if (!JwtUtil.verify(token)) {
            throw new JwtException("token验证不通过");
        }

        if (JwtUtil.isExpired(token)) {
            throw new JwtException("Token过期");
        }
        String username = (String) JwtUtil.getClaim(token).get("username");
        SysUser sysUser = userService.getByUserName(username);
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(sysUser.getUsername(), null, userDetailService.getUserAuthority(sysUser.getId()));
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); //设置认证信息 设置进去就有鉴权了
        chain.doFilter(request, response);
    }
}
